package cn.wangliang181230.boot.web.propertysource;

import org.springframework.core.env.PropertySource;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyFunctionPropertySource extends PropertySource<Object> {

	private static final String PREFIX = "fun.";
	private static final String LOCALIP_PREFIX = "localip";


	public MyFunctionPropertySource(String name) {
		super(name);
	}

	@Override
	public Object getProperty(String name) {
		if (!name.startsWith(PREFIX)) {
			return null;
		}

		// 在配置文件中的配置示例：${fun.localip(192.168.1.*)}

		String type = name.substring(PREFIX.length()); // type示例值：localip(192.168.1.*)

		if (type.startsWith(LOCALIP_PREFIX)) {
			return this.handleLocalIp(type);
		}

		return null;
	}

	private String handleLocalIp(String type) {
		String patterns = type.substring(LOCALIP_PREFIX.length() + 1, type.length() - 1); // patterns示例值：192.168.1.*
		if (patterns.length() == 0) {
			throw new RuntimeException("本机IP匹配串不能为空：" + super.name);
		}

		List<String> localIpList = NetUtil.getIpList(); // 所有网卡的IP列表
		if (localIpList == null || localIpList.isEmpty()) {
			throw new RuntimeException("未获取到任何本机网卡IP信息：" + super.name);
		}

		return findLocalIp(localIpList, patterns);
	}


	private String findLocalIp(List<String> localIpList, String patterns) {
		String ip;
		if (localIpList == null || localIpList.isEmpty()) {
			return null;
		}

		String[] patternArr = patterns.split(",", 10);

		// 先根据入参获取配置
		for (String pattern : patternArr) {
			pattern = pattern.trim();
			if (StringUtils.hasText(pattern)) {
				ip = matchIp(localIpList, pattern);
				if (StringUtils.hasText(ip)) {
					return ip; // 匹配到了IP
				}
			}
		}

		return null;
	}

	static String matchIp(List<String> ipList, String pattern) {
		if (pattern.startsWith("^")) { // 正则匹配
			Pattern p = Pattern.compile(pattern, Pattern.UNICODE_CASE);
			Matcher matcher;
			for (String ip : ipList) {
				matcher = p.matcher(ip);
				if (matcher.matches()) {
					return ip;
				}
			}
		} else {
			for (String ip : ipList) {
				if (PatternUtil.match(pattern, ip)) {
					return ip;
				}
			}
		}

		return null;
	}
}
